package com.cisdi.info.simple.service.permission.impl;

import com.cisdi.info.simple.DDDException;
import com.cisdi.info.simple.dao.permission.ModuleDao;
import com.cisdi.info.simple.dao.permission.OperatorDao;
import com.cisdi.info.simple.dto.base.PageDTO;
import com.cisdi.info.simple.dto.base.PageResultDTO;
import com.cisdi.info.simple.entity.permission.Module;
import com.cisdi.info.simple.entity.permission.ModuleTreeNode;
import com.cisdi.info.simple.service.base.BaseService;
import com.cisdi.info.simple.service.permission.ModuleService;
import com.cisdi.info.simple.util.ModuleManager;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
@Transactional
public class ModuleServiceBean extends BaseService implements ModuleService {

    private static Logger logger = LogManager.getLogger();

    @Autowired
    private ModuleDao moduleDao;

    @Autowired
    private OperatorDao operatorDao;

    public PageResultDTO findModules(PageDTO pageDTO) {
        pageDTO.setStartIndex((pageDTO.getCurrentPage() - 1) * pageDTO.getPageSize());
        List<Module> moduleDTOS = this.moduleDao.findModules(pageDTO);
        Long totalCount = this.moduleDao.findModuleTotalCount(pageDTO);

        PageResultDTO pageResultDTO = new PageResultDTO();
        pageResultDTO.setTotalCount(totalCount);
        pageResultDTO.setDatas(moduleDTOS);

        return pageResultDTO;
    }

    public List<Module> findAllModules() {
        return this.moduleDao.findAllModules();
    }

    public List<Module> findAllModulesWithIdName() {
        return this.moduleDao.findAllModulesWithIdName();
    }

    public Module findModule(Long moduleId) {
        return this.moduleDao.findModule(moduleId);
    }

    //所有外键的Name都以加载
    public Module findModuleWithForeignName(Long moduleId) {
        return this.moduleDao.findModuleWithForeignName(moduleId);
    }

    public Module saveModule(Module module) {
        this.setSavePulicColumns(module);
        return this.moduleDao.saveModule(module);
    }

    public Module updateModule(Module module) {
        this.setUpdatePulicColumns(module);
        return this.moduleDao.updateModule(module);
    }

    public void deleteModule(Long moduleId) {
        this.moduleDao.deleteModule(moduleId);
    }

    public ModuleTreeNode constructNewTree(Long operatorId, String modelType) {
        List<String> permissionCodes = this.operatorDao.findPermissions(operatorId);

        List<ModuleTreeNode> subSystemModules = new ArrayList<ModuleTreeNode>();

        Map<String,ModuleTreeNode> moduleTreeNodes = new HashMap<String, ModuleTreeNode>();
        for(String permissionCode : permissionCodes)
        {
            String[] permissionCodeParts = StringUtils.split(permissionCode, "_");
            String subSystemName = permissionCodeParts[0];
            String moduleName = permissionCodeParts[0]+"/"+permissionCodeParts[1];
            String entityName = permissionCodeParts[0]+"/"+permissionCodeParts[1]+"/"+permissionCodeParts[2];

            if(moduleTreeNodes.containsKey(entityName)) continue;

            ModuleTreeNode subSystemModuleTreeNode = moduleTreeNodes.get(subSystemName);
            if(subSystemModuleTreeNode == null)
            {
                Module subSystemModule = findMoudle(subSystemName);
                if("否".equals(subSystemModule.getIsInUse())) continue;
                subSystemModuleTreeNode = this.convertModule2TreeNode(subSystemModule,1);
                subSystemModules.add(subSystemModuleTreeNode);
                moduleTreeNodes.put( subSystemName,subSystemModuleTreeNode);
            }

            ModuleTreeNode moduleModuleTreeNode = moduleTreeNodes.get(moduleName);
            if(moduleModuleTreeNode == null)
            {
                Module moduleModule = findMoudle(moduleName);
                if("否".equals(moduleModule.getIsInUse())) continue;
                moduleModuleTreeNode = this.convertModule2TreeNode(moduleModule,2);
                subSystemModuleTreeNode.addNode(moduleModuleTreeNode);
                moduleTreeNodes.put( moduleName,moduleModuleTreeNode);
            }
            Module entityModule = findMoudle(entityName);
            if("否".equals(entityModule.getIsInUse())) continue;
            ModuleTreeNode entityModuleTreeNode = this.convertModule2TreeNode(entityModule,3);
            moduleModuleTreeNode.addNode(entityModuleTreeNode);
            moduleTreeNodes.put( entityName,entityModuleTreeNode);
        }
        for(ModuleTreeNode moduleTreeNode : moduleTreeNodes.values()) {
            if(moduleTreeNode.getNodes().size() == 0) continue;;
            Collections.sort(moduleTreeNode.getNodes(), new Comparator<ModuleTreeNode>() {
                @Override
                public int compare(ModuleTreeNode o1, ModuleTreeNode o2) {
                    int i = (int) (o1.getDisplayIndex() - o2.getDisplayIndex());
                    return i;
                }
            });
        }
        ModuleTreeNode rootModuleTreeNode = new ModuleTreeNode();
        rootModuleTreeNode.setId("root");
        rootModuleTreeNode.setName("root");
        rootModuleTreeNode.setText("根节点");
        rootModuleTreeNode.getNodes().addAll(subSystemModules);
        return rootModuleTreeNode;
    }
    private Module findMoudle(String code)
    {
        Module module = ModuleManager.findModule(code);
        if(module == null)
        {
            String error = "没找到模块："+code;
            logger.error(error);
            throw  new DDDException(error);
        }
        return  module;
    }
    private ModuleTreeNode convertModule2TreeNode(Module module,Integer level) {

        ModuleTreeNode treeNode = new ModuleTreeNode();
        treeNode.setText(module.getName());
        treeNode.setId(module.getCode());
        treeNode.setRouteData(module.getRoute());
        treeNode.setLocation(module.getUrl());
        treeNode.setRouteParamsObj(module.getRouteParamsObj());

        treeNode.setLevel(level.toString());
        treeNode.setIsExpanded(false);
        treeNode.setIsSelected(false);

        String iconClass = module.getIconClass();
        if (iconClass != null && (!("".equals(iconClass)))) {
            treeNode.setIcon(iconClass);
        } else {
            //
        }
        return treeNode;
    }



}
